package com.hotel.customersystem.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hotel.config.websocket.WebSocketProcess;
import com.hotel.couponsystem.mapper.CouponStockMapper;
import com.hotel.couponsystem.pojo.CouponStock;
import com.hotel.customersystem.enums.CusOrderDataStatus;
import com.hotel.customersystem.enums.CusOrderStatus;
import com.hotel.customersystem.mapper.CustomerOrderMapper;
import com.hotel.customersystem.mapper.CustomerUserCouponMapper;
import com.hotel.customersystem.mapper.CustomerUserMapper;
import com.hotel.customersystem.pojo.CustomerOrder;
import com.hotel.customersystem.pojo.CustomerUser;
import com.hotel.customersystem.pojo.CustomerOrderDetailVo;
import com.hotel.customersystem.pojo.CustomerUserCoupon;
import com.hotel.customersystem.service.CustomerOrderService;
import com.hotel.customersystem.service.OrderRedisService;

import com.hotel.hotelsystem.mapper.*;
import com.hotel.hotelsystem.pojo.*;
import com.hotel.hotelsystem.service.RoomInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

import static com.hotel.config.rabbitmq.config.OrderDelayConfig.ORDER_DELAY_EXCHANGE_NAME;
import static com.hotel.config.rabbitmq.config.OrderDelayConfig.ORDER_DELAY_QUEUE_ROUTING_KEY;

/**
 * (CustomerOrder)表服务实现类
 *
 * @author makejava
 * @since 2022-09-30 16:21:28
 */
@Slf4j
@Service("customerOrderService")
public class CustomerOrderServiceImpl extends ServiceImpl<CustomerOrderMapper, CustomerOrder> implements CustomerOrderService {
    @Resource
    private CustomerOrderMapper orderMapper;
    @Resource
    private RoomInfoMapper roomInfoMapper;
    @Resource
    private TenantListMapper tenantListMapper;
    @Resource
    private HotelInfoMapper hotelInfoMapper;
    @Resource
    private RoomMapper roomMapper;
    @Resource
    private RabbitTemplate rabbitTemplate;
    @Resource
    private HotelListMapper hotelListMapper;
    @Resource
    private CouponStockMapper couponMapper;
    @Resource
    private OrderRedisService orderRedisService;
    @Resource
    private RoomListMapper roomListMapper;
    @Autowired
    private CustomerUserMapper customerUserMapper;
    @Autowired
    private RoomInfoService roomInfoService;
    @Resource
    private CustomerUserCouponMapper CusCouponMapper;


    @Transactional
    @Override
    public String saveOrder(CustomerOrder order, RoomInfo roomInfo, List<TenantList> tenantList) {
        //设置默认的订单信息
        order.setOrderNo(UUID.randomUUID().toString().replace("-",""));
        order.setOrderTime(LocalDateTime.now());
        order.setCreateTime(LocalDateTime.now());
        order.setOrderStatus(CusOrderStatus.wait_pay.getStatus());

        //保存订单
        int row = orderMapper.insert(order);
        log.info("订单的状态:{}",order.getOrderStatus());

        //查询房间类型相符的房间
        QueryWrapper<Room> qw = new QueryWrapper<>();
        qw.eq("room_status",0);
        qw.eq("room_type_id",roomInfo.getRoomTypeId());
        qw.eq("hotel_id",roomInfo.getHotelId());
        List<Room> rooms = roomMapper.selectList(qw);
        System.out.println("***rooms: "+rooms);

        //查询可使用的房间
        List<Room> fitRooms = new ArrayList<>();
        for(Room room:rooms){
            int roomNum = room.getRoomNum();
            System.out.println("***roomNum: "+roomNum);
            QueryWrapper<RoomInfo> qw1 = new QueryWrapper<>();
            qw1.eq("room_num",roomNum);
            qw1.and(wrapper->
                    wrapper.and(wrapper1->
                                    wrapper1.lt("in_time",order.getCheakInDate()).gt("in_time",order.getCheakOutDate()))
                            .or(wrapper2->
                                    wrapper2.lt("out_time",order.getCheakInDate()).gt("out_time",order.getCheakOutDate()))
                            .or(wrapper3->
                                    wrapper3.eq("in_time",order.getCheakInDate()).eq("out_time",order.getCheakOutDate())));

            List<RoomInfo> roomInfoList = roomInfoMapper.selectList(qw1);//查询该房间号在用户住房期间是否被占用
            System.out.println("****roomInfoList: "+roomInfoList);
            if(roomInfoList.size()==0){
                fitRooms.add(room);
            }
        }
        System.out.println("****fitrooms: "+fitRooms);

        //插入房间预定信息
        roomInfo.setRoomNum(fitRooms.get(0).getRoomNum());
        roomInfo.setInTime(order.getCheakInDate());
        roomInfo.setOutTime(order.getCheakOutDate());
        roomInfo.setOrderId(order.getOrderId());
        int row1 = roomInfoMapper.insert(roomInfo);

        //发送消息延迟队列20min
        //CustomerUser customerUser = customerUserMapper.selectById(order.getUserId());
        Map<String,Object> map = new HashMap<>();
        map.put("orderNo",order.getOrderNo());
        map.put("userId",order.getUserId());
        rabbitTemplate.convertAndSend(ORDER_DELAY_EXCHANGE_NAME,ORDER_DELAY_QUEUE_ROUTING_KEY,map,
                msg -> {
                    //设置消息的过期时间
                    msg.getMessageProperties().setDelay(60000*20);
                    return msg;
                } );
        log.info("现在的时间是：{},发送的消息:{}", LocalDateTime.now(),order.getOrderNo());
        //redis储存设置过期时间15min
        boolean redis = orderRedisService.saveOrder2Redis(order);

        //入住人信息添加
        int row2 = 0;
        for (TenantList tenant:tenantList){
            tenant.setOrderId(order.getOrderId());
            row2 += tenantListMapper.insert(tenant);
        }
        if(row>0&&row1>0&&row2>0)
            return order.getOrderNo();
        else
            return null;
    }

    /**
     * 获取用户订单列表
     * @param userId
     * @return
     */
    @Override
    public List<CustomerOrder> getOrderList(Integer userId) {
        QueryWrapper<CustomerOrder> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id",userId)
                .ne("order_data_status", CusOrderDataStatus.has_delete)
                .orderByDesc("create_time");
        List<CustomerOrder> list = orderMapper.selectList(wrapper);
        for (CustomerOrder order : list) {
            order.setCheckInTime(order.getCheakInDate().toLocalDate());
            order.setCheckOutTime(order.getCheakOutDate().toLocalDate());
        }
        return list;
    }

    /**
     * 获取订单详情
     * @param orderVo
     * @return
     */
    @Transactional
    @Override
    public CustomerOrderDetailVo getOrderDetail(CustomerOrderDetailVo orderVo) {
        //获取入住人信息
        QueryWrapper<TenantList> wrapper = new QueryWrapper<>();
        wrapper.eq("order_id",orderVo.getOrderId())
                .select("tenant_name","tenant_telno");
        List<TenantList> tenantLists = tenantListMapper.selectList(wrapper);

        CustomerOrder order = orderMapper.selectById(orderVo.getOrderId());
        orderVo.setOrderStatus(order.getOrderStatus());

        //查询酒店信息
        QueryWrapper<HotelInfo> wrapper1 = new QueryWrapper<>();
        wrapper1.eq("hotel_id",orderVo.getHotelId())
                .select("hotel_name","hotel_telno","hotel_loc");
        HotelInfo hotelInfo = hotelInfoMapper.selectOne(wrapper1);
        orderVo.setHotelName(hotelInfo.getHotelName());
        orderVo.setHotelLoc(hotelInfo.getHotelLoc());
        orderVo.setHotelTelno(hotelInfo.getHotelTelno());
        orderVo.setTenantList(tenantLists);

        //酒店图片
        QueryWrapper<HotelList> qw = new QueryWrapper<>();
        qw.eq("hotel_id",orderVo.getHotelId());
        HotelList hotelList = hotelListMapper.selectOne(qw);
        orderVo.setHotelImg(hotelList.getHotelShowImg());
        //优惠券
        List<CouponStock> couponList = new ArrayList<>();
        if (orderVo.getStandby01()!=null){
            CouponStock byCouponNo = couponMapper.getByCouponNo(orderVo.getStandby01());
            couponList.add(byCouponNo);
        }
        if (orderVo.getStandby02()!=null){
            CouponStock byCouponNo = couponMapper.getByCouponNo(orderVo.getStandby02());
            couponList.add(byCouponNo);
        }
        orderVo.setCouponList(couponList);
        QueryWrapper<RoomList> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("hotel_id",orderVo.getHotelId()).eq("room_type",orderVo.getRoomType());
        RoomList roomList = roomListMapper.selectOne(queryWrapper);
        orderVo.setOldPrice(roomList.getRoomLeastPrice());
        return orderVo;
    }

    /**
     * 订单20分钟倒计时取消 更改订单和优惠券状态
     * @param orderNo
     * @return
     */
    @Transactional
    @Override
    public Integer orderDelayChangeStatus(String orderNo) {
        QueryWrapper<CustomerOrder> qw = new QueryWrapper<>();
        qw.eq("order_no",orderNo);
        CustomerOrder order = orderMapper.selectOne(qw);
        int row = 0;
        if (order.getOrderStatus()== CusOrderStatus.wait_pay.getStatus()){
            order.setOrderStatus(CusOrderStatus.has_cancel.getStatus());
            order.setUpdateTime(LocalDateTime.now());
            row = orderMapper.updateById(order);
            //删除房间信息
            roomInfoService.deleteByOrderId(order.getOrderId());

            //更改优惠券状态

            CustomerUser customerUser = customerUserMapper.selectById(order.getUserId());
            if (order.getStandby01()!=null){
                QueryWrapper<CustomerUserCoupon> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("coupon_no",order.getStandby01()).eq("standby01",customerUser.getStandby01());
                CustomerUserCoupon byCouponNo = CusCouponMapper.selectOne(queryWrapper);
                if (byCouponNo.getCouponUseStatus()==3){
                    byCouponNo.setState(0);
                }
                CusCouponMapper.updateById(byCouponNo);
            }
            if (order.getStandby02()!=null){
                QueryWrapper<CustomerUserCoupon> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("coupon_no",order.getStandby02()).eq("standby01",customerUser.getStandby01());
                CustomerUserCoupon byCouponNo = CusCouponMapper.selectOne(queryWrapper);
                if (byCouponNo.getCouponUseStatus()==3){
                    byCouponNo.setState(0);
                }
                CusCouponMapper.updateById(byCouponNo);
            }
        }
        return row;
    }

    /**
     * 订单分页查询
     * @param userId
     * @param currentPage
     * @param pageSize
     * @return
     */
    @Override
    public IPage<CustomerOrder> selectByPage(Integer userId, Integer currentPage, Integer pageSize) {
        Page<CustomerOrder> page=new Page<>(currentPage,pageSize);
        System.out.println(page.getSize());
        QueryWrapper<CustomerOrder> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id",userId)
                .ne("order_data_status", CusOrderDataStatus.has_delete)
                .orderByDesc("create_time");
        IPage<CustomerOrder> page2 = orderMapper.selectPage(page,wrapper);
        List<CustomerOrder> records = page2.getRecords();
        for (CustomerOrder order : records) {
            order.setCheckInTime(order.getCheakInDate().toLocalDate());
            order.setCheckOutTime(order.getCheakOutDate().toLocalDate());
        }
        return page2;
    }
}

